home *** CD-ROM | disk | FTP | other *** search
/ Computer Select (Limited Edition) / Computer Select.iso / dobbs / v16n07 / coff.asc < prev    next >
Encoding:
Text File  |  1991-06-11  |  14.9 KB  |  481 lines

  1. _A COFF FILE LOADER FOR THE 34010_
  2. by Don Morgan
  3.  
  4.  
  5.  
  6. [LISTING ONE]
  7.  
  8. #include <fcntl.h>
  9. #include <sys\types.h>
  10. #include <sys\stat.h>
  11. #include <io.h>
  12. #include <conio.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <malloc.h>
  16. #include <stdlib.h>
  17. #include "coff.h"
  18.  
  19. struct main_header *m_hdr;
  20. struct opt_header *opt;
  21. struct sect_header section;
  22.  
  23. void main(int argc, char **argv)
  24. {
  25. /**************** PART A *****************/
  26.         int module, size, header, sect, j;
  27.         unsigned long result;
  28.         int bss_done = FALSE;
  29.         
  30.         unsigned char *receive_buffer;
  31.         char tmp_buf[100];
  32.         int data, i;
  33.         if(argc != 2) {
  34.                 printf("\nno file given!");
  35.                 exit(-1);
  36.                 }
  37.         module = open(argv[1], O_BINARY|O_RDONLY);
  38.         if(module == -1){
  39.                 perror("\nopen failed!");
  40.                 exit(-1);
  41.                               }
  42.         /**************************/
  43.         /*read coff file into buffer*/
  44.         size = filelength(module);
  45.         file_buffer = (char *)malloc(size);
  46.         if(file_buffer == NULL) {
  47.                 perror("\nnot enough memory!");
  48.                 exit (-1);
  49.                 }
  50.         if((result = (long)read(module, file_buffer, size)) <= 0) {
  51.                 perror("\ncan't find file!\n");
  52.                 exit(-1);
  53.                 }
  54.         close(module);
  55.  
  56. /************  PART B    *************/
  57. /*set up 34010 for loading*/
  58. /**************************/
  59. /*it is the users responsibility to set up the cntrl register*/
  60. /*please note that some of the register settings, such as the following*/
  61. /*are application dependent, this code is included only to show an*/
  62. /*example of low level setup for the 34010*/
  63.         gsp_poke(cntrl, 0x4);  /*sets cas before ras refresh*/
  64.         
  65. /**************************/
  66. /*set up 34010 to restart correctly after loading program*/
  67.         put_hstctl(hlt | cf | incr | incw | nmim | nmi_flg);
  68.         data = get_hstctl();
  69.         if(data != (hlt | cf | incr | incw | nmim | nmi_flg)) {
  70.                 printf("\nerror writing to hstctl!");
  71.                 exit(-1);
  72.                               }
  73.  
  74. /************ PART C  *************/
  75. /**************************/
  76. /*get contents of main header*/
  77.         m_hdr = (struct main_header *) file_buffer;
  78. /*see if the file has a magic number*/
  79.         if(m_hdr->magic_num !=FILE_MAGIC) {
  80.                 printf("\nnot a standard coff .out file!");
  81.                 exit(-1);
  82.                 }
  83. /*check to see whether there is an optional header*/
  84.         if((m_hdr->opt_head != OPT_XST)){ 
  85.                 printf("file is not fully linked!");
  86.                 exit(-1);
  87.                 }
  88. /*get contents of optional header*/
  89.         opt = (struct opt_header *) &file_buffer[OPT_OFST];
  90. /*see if the optional header has a magic number*/
  91.         if(opt->magic_num !=OPT_MAGIC) {
  92.                 printf("\nnon standard file!");
  93.                 exit(-1);
  94.                 }
  95.                 
  96. /*************************************************/ 
  97. /*begin searching for and loading section headers find bss section first! */ 
  98.        i = FIRST_HDR;
  99.        for (j=0;((j<m_hdr->num_sects) && !bss_done) ;j++){
  100.                strcpy(tmp_buf,&file_buffer[i]);
  101.                if(!bss_done) {
  102.                        if(!(strcmp(tmp_buf, ".bss"))) {
  103.                                strcpy(section.name, tmp_buf);
  104.                                header = i;
  105.                                get_sect(header);
  106.                                bss_done =     TRUE;
  107.                                }
  108.                        }
  109.                i += SEC_OFST;
  110.                }
  111.        /*now load the other sections*/                
  112.        i = FIRST_HDR;
  113.        for (j=0; j<m_hdr->num_sects;j++){
  114.                strcpy(tmp_buf,&file_buffer[i]);
  115.                if(strcmp(tmp_buf, ".bss")) {
  116.                        strcpy(section.name, tmp_buf);
  117.                        header = i;
  118.                        get_sect(header);
  119.                        }
  120.                i += SEC_OFST;
  121.                }
  122.  
  123.          /*release memory for file buffer*/
  124.        free(file_buffer);
  125.      
  126. /************ PART D *************/
  127. /*set up reset and interrupt vectors for the 34010                 */
  128. /*usually, both the nmi and halt bits are set and then released    */
  129. /*this code may differ depending upon the desires of the programmer */
  130.      gsp_poke(intenb,0x0);  /*no interrupts*/
  131.      gsp_poke(nmi_vect, opt->entry_point);
  132.      gsp_poke(nmi_vect+0x10, opt->entry_point >> 0x10);
  133.      gsp_poke(reset,opt->entry_point);
  134.      gsp_poke(reset+0x10,opt->entry_point >> 0x10);
  135.      put_hstctl(hlt | incr | nmi_flg | incw | nmim);
  136.                   /*toggle the halt bit and go*/
  137.      data = get_hstctl();
  138.      data &= ~hlt;
  139.      put_hstctl( data );
  140. }
  141.  
  142. /*********** PART E *************/
  143. void get_sect(header)
  144. int header;
  145. {
  146.      struct sect_header * ptr = (struct sect_header *)&file_buffer[header];
  147.      load(ptr);
  148. }
  149. void load(ptr)
  150. struct sect_header *ptr;
  151. {
  152. /*here the flags are checked to determine whether the section is to be 
  153. loaded or copied or ignored*/
  154.        if((ptr->sect_size) && !(ptr->flags & STYP_DSECT) &&
  155.                !(ptr->flags & STYP_NOLOAD)) {
  156.                        if(!(strcmp(ptr->name,".cinit")) 
  157.                                && (ptr->flags & STYP_COPY)) 
  158.                                        put_data(ptr);
  159.                        else
  160.                        if(((ptr->flags & STYP_TEXT)
  161.                                || (ptr->flags & STYP_DATA) 
  162.                                        || (!(strcmp(ptr->name,".cinit") 
  163.                                           && !(ptr->flags &   STYP_COPY))))) 
  164.                                                        load_block(ptr);
  165.        }
  166. }      
  167. void load_block(ptr)
  168. struct sect_header *ptr;
  169. {      
  170.        int data, temporary, hldr, limit;
  171.        long i, j, file_pointer;
  172.        file_pointer = ptr->raw_data;
  173. /*set the host interface up to point at the correct address*/
  174. #if MM
  175.        *(gsp:>hstadrl) = ptr->virt_addr;
  176.        *(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
  177. #else
  178.        outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
  179.        outpw(io_hstadrh, (unsigned int)ptr->virt_addr >> 0x10);
  180. #endif
  181.        limit = (ptr->sect_size/0x10)-1;
  182.        j=0;
  183.        /*write each word to host interface*/
  184.        for(i=0; i<=limit; i++){
  185. /*get the data from the file buffer and get it in the correct order 
  186. before writing to the host interface*/
  187.                  data = (file_buffer[file_pointer+j++]&0xff);
  188.            data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  189. #if MM
  190.            *(gsp:>hstdata) = data;
  191. #else
  192.            outpw(io_hstdata,data);
  193. #endif
  194.                  }
  195.        /*compare data*/
  196.       /*point at the correct address*/ 
  197. #if MM
  198.        *(gsp:>hstadrl) = ptr->virt_addr;
  199.        *(gsp:>hstadrh) = ptr->virt_addr >> 0x10;
  200. #else
  201.        outpw(io_hstadrl, (unsigned int)ptr->virt_addr);
  202.        outpw(io_hstadrh, (unsigned int)ptr->virt_addr>> 0x10);
  203. #endif
  204.        limit = (ptr->sect_size/0x10)-1;
  205.        j=0;
  206.        for(i=0; i<=limit; i++){
  207.                        /*get the data*/
  208.                  data = (file_buffer[file_pointer+j++]&0xff);
  209.            data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  210. #if MM
  211.            hldr = *(gsp:>hstdata);
  212. #else
  213.            hldr = inpw(io_hstdata);
  214. #endif
  215.            if(hldr != data)
  216.                  printf("\ncompare error!");
  217.            }
  218. }
  219. void put_data(ptr)
  220. struct sect_header *ptr;
  221. {
  222.        int data, temporary, hldr, limit, num_words, num;
  223.        long i, j, reloc_address, file_pointer;
  224.        struct init_table * init;
  225.        file_pointer = ptr->raw_data;
  226.        do{
  227.      init = (struct init_table *)&file_buffer[file_pointer];
  228.                  reloc_address = init->ptr_to_var;
  229.            file_pointer += 6;
  230.  
  231. /*point at relocation address*/
  232. #if MM
  233.            *(gsp:>hstadrl) = reloc_address;
  234.            *(gsp:>hstadrh) = reloc_address >> 0x10;
  235. #else
  236.            outpw(io_hstadrl, (unsigned int)reloc_address);
  237.            outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
  238. #endif
  239.  
  240. /*determine the amount of data to transfer and do it*/     
  241.            num_words = init->num_words;
  242.            limit = --num_words;
  243.            j=0;
  244.            for(i=0; i<=limit; i++){
  245.                  data = (file_buffer[file_pointer+j++]&0xff);
  246.                  data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  247. #if MM
  248.               *(gsp:>hstdata) = data;
  249. #else
  250.               outpw(io_hstdata,data);
  251. #endif
  252.               }
  253.                /*now, do a data compare*/
  254. #if MM
  255.            *(gsp:>hstadrl) = reloc_address;
  256.            *(gsp:>hstadrh) = reloc_address >> 0x10;
  257. #else
  258.            outpw(io_hstadrl, (unsigned int)reloc_address);
  259.            outpw(io_hstadrh, (unsigned int)reloc_address >> 0x10);
  260. #endif
  261.            num_words = init->num_words;
  262.            limit = --num_words;
  263.            j=0;
  264.            for(i=0; i<=limit; i++){
  265.                  data = (file_buffer[file_pointer+j++]&0xff);
  266.               data += ((file_buffer[file_pointer+j++]&0xff)*0x100);
  267. #if MM
  268.               hldr = *(gsp:>hstdata);
  269. #else
  270.               hldr = inpw(io_hstdata);
  271. #endif
  272.               if(hldr != data)
  273.                         printf("\ndata compare error!");
  274.               }
  275.        file_pointer += j;     
  276.      }while(((int)file_buffer[file_pointer]) != 0x0);
  277. }
  278. /*set up the hstctl*/
  279. void put_hstctl(unsigned int value)
  280. {
  281. #if MM
  282.        *(gsp:>hstctl) = value;
  283. #else
  284.        outpw(io_hstctl,value);
  285. #endif
  286. }
  287. /*get current Hstclt setting*/
  288. unsigned int get_hstctl()
  289. {
  290.        int value;
  291. #if MM
  292.        value = *(gsp:>hstctl);
  293. #else
  294.        value = inpw(io_hstctl);
  295. #endif
  296.        return value;
  297. }
  298. /*set host interface to point at correct address*/
  299. void set_addr(unsigned long address)
  300. {
  301. #if MM
  302.        *(gsp:>hstadrl) = address;
  303.        *(gsp:>hstadrh) = address >> 0x10;
  304. #else
  305.        outpw(io_hstadrl,(unsigned int)address);
  306.        outpw(io_hstadrh,(unsigned int)address >> 0x10);
  307. #endif
  308. }
  309. void gsp_poke(unsigned long address, unsigned long value)
  310. {
  311.        set_addr(address);
  312. #if MM
  313.        *(gsp:>hstdata) = value;
  314. #else
  315.        outpw(io_hstdata,(unsigned int)value);
  316. #endif
  317. }
  318. unsigned int gsp_peek(unsigned long address)
  319. {
  320.        int value;
  321.        
  322.        set_addr(address);
  323. #if MM
  324.        value = *(gsp:>hstdata);
  325. #else
  326.        value = inpw(io_hstdata);
  327. #endif
  328.        return value;
  329. }
  330.   
  331.   
  332.  
  333.  
  334. [LISTING TWO]
  335.  
  336. #define FALSE 0
  337. #define TRUE 0x1
  338.  
  339. #define MM TRUE
  340.  
  341. /*physical addresses of memory mapped host interface*/
  342. #if MM
  343. _segment gsp = 0xc700;
  344. int _based(void) *hstctl = (int _based(void)*)0xe00;
  345. int _based(void) *hstdata = (int _based(void)*)0xf00;
  346. int _based(void) *hstadrh = (int _based(void)*)0xc00;
  347. int _based(void) *hstadrl = (int _based(void)*)0xd00;
  348. #else
  349. /*io mapped addresses of host interface*/
  350. io_hstctl = 0;
  351. io_hstdata = 0;
  352. io_hstadrh = 0;
  353. io_hstadrl = 0;
  354. #endif
  355.  
  356. #define FILE_MAGIC 0x90
  357. #define OPT_MAGIC 0x108
  358. #define OPT_XST 0x1c
  359. #define OPT_OFST 0x14
  360. #define SEC_OFST 0x28
  361. #define FIRST_HDR 0x30
  362.  
  363. #define cf 0x4000
  364. #define hlt 0x8000
  365. #define nmi_flg 0x100
  366. #define nmim 0x200
  367. #define incw 0x800
  368. #define incr 0x1000
  369.  
  370. /*definitions*/
  371. /*file header flags*/
  372. #define F_RELFLG 0x1               /*relocation information stripped*/
  373. #define F_EXEC 0x2                 /*file is relocateable*/
  374. #define F_LNNO 0x4                 /*line numbers stripped*/
  375. #define F_LSYMS 0x10               /*local symbos stripped*/
  376. #define F_QR32WR 0x40              /*34010 byte ordering*/
  377.  
  378. /*section header flags*/
  379. #define STYP_REG 0x0               /*regular section*/
  380. #define STYP_DSECT 0x1             /*dummy section*/
  381. #define STYP_NOLOAD 0x2            /*noload section*/
  382. #define STYP_GROUP 0x4             /*grouped section*/
  383. #define STYP_PAD 0x8               /*padding section*/
  384. #define STYP_COPY 0x10             /*copy section, important for .cinit*/
  385. #define STYP_TEXT 0x20             /*executable code*/
  386. #define STYP_DATA 0x40             /*initialized data*/
  387. #define STYP_BSS 0x80              /*uninitialized data*/
  388. #define STYP_ALIGN 0x100           /*aligned on cache boundary*/
  389.  
  390. /*******************************************************/
  391. /*interrupt vector:*/
  392. #define reset          0xffffffe0
  393. #define nmi_vect       0xfffffee0
  394. /*******************************************************/
  395. /*i/o registers:*/
  396. #define refcnt         0xc00001f0
  397. #define dpyadr         0xc00001e0
  398. #define vcount         0xc00001d0
  399. #define hcount         0xc00001c0
  400. #define dpytap         0xc00001b0
  401. #define pmask          0xc0000160
  402. #define psize          0xc0000150
  403. #define convdp         0xc0000140
  404. #define convsp         0xc0000130
  405. #define intpend        0xc0000120
  406. #define intenb         0xc0000110
  407. #define hstctlh        0xc0000100
  408. #define hstctll        0xc00000f0
  409. #define hst_adrh       0xc00000d0
  410. #define hst_adrl       0xc00000e0
  411. #define hst_data       0xc00000c0
  412. #define cntrl          0xc00000b0
  413. #define dpyint         0xc00000a0
  414. #define dpystrt        0xc0000090
  415. #define dpyctl         0xc0000080
  416. #define vtotal         0xc0000070
  417. #define vsblnk         0xc0000060
  418. #define veblnk         0xc0000050
  419. #define vesync         0xc0000040
  420. #define htotal         0xc0000030
  421. #define hsblnk         0xc0000020
  422. #define heblnk         0xc0000010
  423. #define hesync         0xc0000000
  424. #define dac_wr         0xc7800
  425. #define ppl_rd         0xc7000
  426.  
  427. /*header structures*/
  428. struct main_header {
  429.      unsigned short int magic_num;
  430.      unsigned short int num_sects;
  431.      long int date_stamp;
  432.      long int sym_table;
  433.      long int entries;
  434.      unsigned short int opt_head;
  435.      unsigned short int flags;
  436.      };
  437. struct opt_header {
  438.      short int magic_num;
  439.      short int version;
  440.      unsigned long code_size;
  441.      unsigned long init_size;
  442.      unsigned long uninit_size;
  443.      unsigned long entry_point;
  444.      unsigned long start_text;
  445.      unsigned long start_data;
  446.      };
  447. struct sect_header {
  448.      unsigned char name[8];
  449.      unsigned long phys_addr;
  450.      unsigned long virt_addr;
  451.      unsigned long sect_size;
  452.      unsigned long raw_data;
  453.      unsigned long reloc;
  454.      unsigned long num_entries;
  455.      unsigned short int reloc_entries;
  456.      unsigned short int line_entries;
  457.      unsigned short int flags;
  458.      unsigned char ch1;
  459.      unsigned char page;
  460.      };
  461. struct init_table {
  462.      int num_words;
  463.      long ptr_to_var;
  464.      };
  465. /*video pointer*/
  466. char far *vid_mem;
  467. /*variable declarations*/
  468. int len, text_ptr, debug, coff_debug, fake;
  469. unsigned char *file_buffer;
  470. /*function prototypes*/
  471. long getint(int, int);
  472. void load(struct sect_header *);
  473. void load_block(struct sect_header *);
  474. void put_data(struct sect_header *);
  475. void put_hstctl(unsigned int);
  476. unsigned int get_hstctl(void);
  477. void set_addr(unsigned long int);
  478. void gsp_poke(unsigned long int, unsigned long int);
  479. unsigned int gsp_peek(unsigned long int);
  480. void get_sect(int);
  481.   
  482.  
  483.